<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

    <link rel="stylesheet" href="codemirror/lib/codemirror.css">
    <script src="codemirror/lib/codemirror.js"></script>

    <link rel="stylesheet" href="codemirror/theme/juejin.min.css">

    <script src="codemirror/modes/markdown/markdown.js"></script>
    <script src="codemirror/modes/xml/xml.js"></script>
    <style>
        /* 遮罩层 */
        .overlay {
            position: fixed;
            top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0, 0, 0, 0.5);
            display: none;
            justify-content: center;
            align-items: center;
            z-index: 999;
        }

        /* 旋转加载动画 */
        .loader {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #007bff;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>

<body>
    <script>
        const imgType = ['image/bmp', 'image/png', 'image/jpeg', 'image/gif', 'video/mp4'];
        let tempEvent = null;
        CodeMirror.keyMap["default"]["Cmd-/"] = "toggleComment";  // Add-on
        let isScrollingFromScript = false;
        var editor = CodeMirror(document.body, {
            lineNumbers: false,
            autofocus: true,
            mode: "markdown",
            theme: "juejin",
            showInvisibles: false,
            maxInvisibles: 16,
            autoCloseTags: true,
            smartIndent: true,
            tabSize: 2,
            indentUnit: 2,
            lineWrapping: true,
            readOnly: false,
            autoCloseBrackets: true,
            selectionPointer: true,
            extraKeys: {
                "Cmd-F": "findPersistent",
                "Ctrl-Space": "autocomplete",
                "Ctrl-I": "indentAuto"
            },
            styleActiveLine: true
        });
        editor.on("change", function (instance, change) {
            var content = getContent();
            window.webkit.messageHandlers.contentChangeHandler.postMessage(content);
        });
        
        editor.on("paste", async function(cm, event) {
            const files = event.clipboardData.files;
            if (files) {
                const file = files[0];
                if (file && file.type && imgType.includes(file.type)) {
                    event.preventDefault();
                    tempEvent = event;
                    await uploadLocalImage(file);
                    if (url) {
                        const insertedText = `![](${url})`;
                        editor.replaceSelection(insertedText);
                    }
                }
            }
        });
        
        editor.on("drop", async function(cm, event) {
            event.preventDefault();
            tempEvent = event;
            const files = event.dataTransfer.files;
            if (files) {
                handleFiles(files, event);
            }
        });

        function setTabInsertSpaces(flag) {
            // See http://codemirror.net/doc/manual.html#keymaps
            if (flag) {
                CodeMirror.keyMap["basic"]["Tab"] = function (cm) {
                    var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
                    cm.replaceSelection(spaces, "end", "+input");
                };
            } else {
                CodeMirror.keyMap["basic"]["Tab"] = "defaultTab";
            }
        }

        function setContent(content) {
            editor.doc.setValue(content);
            editor.doc.clearHistory();
            editor.doc.markClean();
        }

        function getContent() {
            return editor.doc.getValue();
        }

        function scroll(scrollFactor) {
            isScrollingFromScript = true;
            window.scrollTo(0, document.body.scrollHeight * scrollFactor);
            requestAnimationFrame(() => isScrollingFromScript = false);
        }

        window.onscroll = function () {
            if (!isScrollingFromScript) {
                window.webkit.messageHandlers.scrollHandler.postMessage({ y0: window.scrollY / document.body.scrollHeight });
            }
        };

        setTabInsertSpaces(true);

        document.addEventListener('click', function (event) {
            window.webkit.messageHandlers.clickHandler.postMessage(null);
        });
        
        async function handleFiles(files, event) {
            for (let i = 0; i < files.length; i++) {
                const file = files[i];
                if (file.type === "text/markdown") {
                    const reader = new FileReader();
                    reader.onload = function(e) {
                        const content = e.target.result;
                        setContent(content);
                    };
                    reader.onerror = function(e) {
                        throwError(`读取文件出错: ${e.target.error}`);
                    };
                    reader.readAsText(file);
                } else if (imgType.includes(file.type)) {
                    await uploadLocalImage(file);
                    
                } else {
                    throwError('不支持的文件类型');
                }

                if (i > 0) {
                    break; // 暂时只支持一个文件
                }
            }
        }

        async function uploadLocalImage(file) {
            showOverlay();
            try {
                doUpload(file);
            } catch (error) {
                throwError(`${error}`);
            }
        }
        
        async function doUpload(file) {
            const arrayBuffer = await file.arrayBuffer();
            const uint8Array = new Uint8Array(arrayBuffer);
            window.webkit.messageHandlers.uploadHandler.postMessage({
                name: file.name,
                type: file.type,
                size: file.size,
                data: Array.from(uint8Array) // 转成普通数组（避免 TypedArray 兼容性问题）
            });
        }

        function throwError(msg) {
            window.webkit.messageHandlers.errorHandler.postMessage(msg);
        }
        
        // 显示遮罩层
        function showOverlay() {
            document.getElementById("overlay").style.display = "flex";
        }

        // 隐藏遮罩层
        function hideOverlay() {
            document.getElementById("overlay").style.display = "none";
        }
        
        function onFileUploadComplete(url) {
            if (url) {
                const insertedText = `![](${url})`;
                if (tempEvent instanceof DragEvent) {
                    let x = tempEvent.pageX;
                    let y = tempEvent.pageY;
                    editor.setCursor(editor.coordsChar({left:x,top:y}));
                    editor.replaceRange(insertedText, editor.getCursor());
                    // 移动光标到插入文本的末尾
                    const newCursor = {
                        line: editor.getCursor().line,
                        ch: editor.getCursor().ch + insertedText.length,
                    };
                    editor.setCursor(newCursor);
                } else { // ClipboardEvent
                    editor.replaceSelection(insertedText);
                }
                
            }
            hideOverlay();
        }

        window.webkit.messageHandlers.loadHandler.postMessage(null);

    </script>
    <div class="overlay" id="overlay">
        <div class="loader"></div>
    </div>
</body>

</html>
